package com.cn.springcloudwechat.common.weiXinPay.xmlUntil;

import com.cn.springcloudwechat.common.utils.Util;
import org.jdom.Element;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.*;
import java.util.HashMap;
import java.util.Map;


/**
 * @author x.c
 * @address 成都云函科技有限公司
 * @time 2017年11月30日
 */
public class XMLUtil {
	/**
	 * 将对象直接转换成String类型的 XML输出
	 * 
	 * @param obj
	 * @return
	 */
	public static String convertToXml(Object obj) {
		// 创建输出流
		StringWriter sw = new StringWriter();
		try {
			// 利用jdk中自带的转换类实现
			JAXBContext context = JAXBContext.newInstance(obj.getClass());

			Marshaller marshaller = context.createMarshaller();
			// 格式化xml输出的格式
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			// 将对象转换成输出流形式的xml
			marshaller.marshal(obj, sw);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return sw.toString();
	}

	/**
	 * 将对象根据路径转换成xml文件
	 * @param obj
	 * @param path
	 * @return
	 */
	public static void convertToXml(Object obj, String path) {
		try {
			// 利用jdk中自带的转换类实现
			JAXBContext context = JAXBContext.newInstance(obj.getClass());

			Marshaller marshaller = context.createMarshaller();
			// 格式化xml输出的格式
			marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			// 将对象转换成输出流形式的xml
			// 创建输出流
			FileWriter fw = null;
			try {
				fw = new FileWriter(path);
			} catch (IOException e) {
				e.printStackTrace();
			}
			marshaller.marshal(obj, fw);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 将String类型的xml转换成对象
	 */
	public static Object convertXmlStrToObject(Class<?> clazz, String xmlStr) {
		Object xmlObject = null;
		try {
			JAXBContext context = JAXBContext.newInstance(clazz);
			// 进行将Xml转成对象的核心接口
			Unmarshaller unmarshaller = context.createUnmarshaller();
			StringReader sr = new StringReader(xmlStr);
			xmlObject = unmarshaller.unmarshal(sr);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return xmlObject;
	}

	/**
	 * 将file类型的xml转换成对象
	 */
	public static Object convertXmlFileToObject(Class<?> clazz, String xmlPath) {
		Object xmlObject = null;
		try {
			JAXBContext context = JAXBContext.newInstance(clazz);
			Unmarshaller unmarshaller = context.createUnmarshaller();
			FileReader fr = null;
			try {
				fr = new FileReader(xmlPath);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			xmlObject = unmarshaller.unmarshal(fr);
		} catch (JAXBException e) {
			e.printStackTrace();
		}
		return xmlObject;
	}

//	@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
//	private static Map iterateElement(Element element) {
//		List jiedian = element.getChildren();
//		Element et = null;
//		Map obj = new HashMap();
//		List list = null;
//		for (int i = 0; i < jiedian.size(); i++) {
//			list = new LinkedList();
//			et = (Element) jiedian.get(i);
//			if (et.getTextTrim().equals("")) {
//				if (et.getChildren().size() == 0)
//					continue;
//				if (obj.containsKey(et.getName())) {
//					list = (List) obj.get(et.getName());
//				}
//				list.add(iterateElement(et));
//				obj.put(et.getName(), list);
//			} else {
//				if (obj.containsKey(et.getName())) {
//					list = (List) obj.get(et.getName());
//				}
//				list.add(et.getTextTrim());
//				obj.put(et.getName(), list);
//			}
//		}
//		return obj;
//	}
	/**
	 * 将xmlString转换成Map
	 *@方法名:getMapFromXML
	 *@描述:
	 *@param xmlString
	 *@return
	 *@throws ParserConfigurationException
	 *@throws IOException
	 *@throws SAXException
	 */
	 public static Map<String,Object> getMapFromXML(String xmlString) throws ParserConfigurationException, IOException, SAXException {
	        //这里用Dom的方式解析回包的最主要目的是防止API新增回包字段
	        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
	        DocumentBuilder builder = factory.newDocumentBuilder();
	        InputStream is =  Util.getStringStream(xmlString);
	        Document document = builder.parse(is);
	        //获取到document里面的全部结点
	        NodeList allNodes = document.getFirstChild().getChildNodes();
	        Node node;
	        Map<String, Object> map = new HashMap<String, Object>();
	        int i=0;
	        while (i < allNodes.getLength()) {
	            node = allNodes.item(i);
	            if(node instanceof Element){
	                map.put(node.getNodeName(),node.getTextContent());
	            }
	            i++;
	        }
	        return map;
	    }
}
